home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
kcl.lha
/
c
/
fasl_pass1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-04
|
10KB
|
430 lines
/*
(C) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
*/
/*
fasl_pass1.c
DG-SPECIFIC
fasl loader pass1 routines
*/
#include "include.h"
#include "../h/fasl.h"
#include "../h/fasl_global.h"
#ifdef AOSVS
#define ERSNF 077014 /* symbol not found error */
#endif
int debug;
init_pass1()
{
short i = 0;
fas_buffp = fas_io_buff;
fas_temp_buff = fas_table_buff;
fas_routine_addr = 0; /* initialize routine addr */
zero(fas_temp_buff, FAS_BUFF_LEN);
/* zero((char *)fas_map, FAS_MAP_SIZE * 4); */
fas_temp_curr = fas_temp_last = 0;
#ifdef AOSVS
if (fas_stchan == -1) fasl_openst();
#endif
fasl_open_temp();
max_part_no = 0;
for (i = 1; i <= MAX_SYS_PART; i++)
fasl_new_table();
fas_relocation_by_table = TRUE;
vs_base_no = vs_top_no = fas_short_no = -1;
}
data_pass1()
{
FAS_HDR_P hdr_p;
FAS_DATA_P data_p;
short base, reloc, reloc_ex;
short *base_p, *dword_p;
int obnum, repeat_count, displacement;
int words, total_len, over_write;
/* set up pointers */
hdr_p = (FAS_HDR_P)fas_buffp;
data_p = (FAS_DATA_P)(fas_buffp + FAS_HEADER_BLEN);
obnum = hdr_p->hdr_num; /* block number */
base = data_p->data_base;
if (datab_rev < 2)
repeat_count = 1;
else
repeat_count = data_p->data_repeat;
words = (int)(data_p->data_words) * repeat_count;
if (base > max_part_no) fasl_invalid();
/* relocation */
base_p = &base;
dword_p = &(data_p->data_disp);
reloc = (data_p->data_reloc) & RELOC_OP;
reloc_ex = ((data_p->data_reloc) & RELOC_OP_EX) >> RELOC_OP_S;
if (reloc != EX_RELOC) unexpect_reloc(reloc);
relocation(reloc_ex, base_p, dword_p);
displacement = data_p->data_disp;
part_table_p = fasl_get_table(base);
total_len = part_table_p->part_len;
if ((displacement + words) > total_len)
total_len = displacement + words;
part_table_p->part_len = total_len;
}
titl_pass1()
{
FAS_HDR_P hdr_p;
FAS_TITL_P titl_p;
short bnum;
char title_buff[MAX_TITLE+1];
char *work_ptr, *work_ptr1;
short title_len;
bnum = ((FAS_HDR_P)fas_buffp)->hdr_num;
if (bnum != 1) fasl_invalid();
/*
titl_p = (FAS_HDR_P)(fas_buffp + FAS_HEADER_BLEN);
title_len = titl_p->titl_len;
work_ptr = fas_buffp + (titl_p->titl_ptr);
work_ptr1 = title_buff;
while ( title_len-- > 0)
*(work_ptr1++) = *(work_ptr++);
*work_ptr1 = '\0';
if (debug) printf("; Loading %s\n",title_buff);
*/
}
ext_pass1()
{
FAS_HDR_P hdr_p;
FAS_ENT_P ent_p;
FAS_NAME_P name_p;
short base, sym_count, symbol_len;
char *work_ptr, *work_ptr1;
int symval;
int ier;
/* set up pointers */
hdr_p = (FAS_HDR_P)fas_buffp;
ent_p = (FAS_ENT_P)(fas_buffp + FAS_HEADER_BLEN);
name_p = (FAS_NAME_P)(ent_p + 1);
sym_count = ent_p->ent_count;
while (sym_count-- > 0) {
part_table_p = fasl_new_table();
part_table_p->part_symbol = TRUE;
/* set symbol flag */
symbol_len = (name_p->name_len) & L_MASK;
work_ptr = fas_buffp + (name_p->name_ptr);
work_ptr1 = part_table_p->part_name;
while(symbol_len-- > 0) /* copy symbol */
*work_ptr1++ = *work_ptr++;
ier = fasl_st(part_table_p->part_name, &symval);
#ifdef AOSVS
if (ier != 0)
if (ier == ERSNF)
/* ignore .REQUIRE_LANG_RT_REV_??.?? */
if ((name_p->name_len) & L_MASK < 16 ||
strncmp(part_table_p->part_name,
".REQUIRE_LANG_RT", 16) != 0) {
fasl_undefined(part_table_p->part_name);
} else {
part_table_p->part_addr = -1;
}
else
sys_emes(ier);
else
part_table_p->part_addr = symval;
#endif
#ifdef DGUX
if (ier != 0)
/* ignore .REQUIRE_LANG_RT_REV_??.?? */
if ((name_p->name_len) & L_MASK < 16 ||
strncmp(part_table_p->part_name,
".REQUIRE_LANG_RT", 16) != 0) {
fasl_undefined(part_table_p->part_name);
} else
part_table_p->part_addr = -1;
else
part_table_p->part_addr = symval;
#endif
name_p += 1; /* advance for next symbol */
}
}
pat_pass1()
{
FAS_HDR_P hdr_p;
FAS_PAT_P pat_p;
FAS_PATD_P patd_p;
short base, pat_count, flags;
long p_len; /* partition length */
short p_name_len; /* partion name length */
char *work_ptr, *work_ptr1;
int symval;
int ier;
/* set up pointers */
hdr_p = (FAS_HDR_P)fas_buffp;
pat_p = (FAS_PAT_P)(fas_buffp + FAS_HEADER_BLEN);
patd_p = (FAS_PATD_P)(pat_p + 1);
pat_count = pat_p->pat_count;
while (pat_count-- > 0) { /* for each descripter */
part_table_p = fasl_new_table();
flags = patd_p->patd_flag; /* various flags */
part_table_p->part_align = (flags & PAT_ALN) >> PAT_ALN_S;
if (part_table_p->part_align > 1) fasl_align_error();
part_table_p->part_global = (flags & PAT_BASE) >> PAT_BASE_S;
part_table_p->part_len = patd_p->patd_len;
p_name_len = (patd_p->patd_nlen) & L_MASK;
/* check short NREL */
if (((flags & PAT_NREL) != 0) &&
(part_table_p->part_global == FALSE)) {
/* part_table_p->part_addr = fas_short_nrel; */
fas_short_no = part_table_p->part_no;
goto NEXT;
}
work_ptr = fas_buffp + (patd_p->patd_nptr);
work_ptr1 = part_table_p->part_name;
while (p_name_len-- > 0) /* copy name */
*work_ptr1++ = *work_ptr++;
if (vs_base_no < 0 &&
strcmp(part_table_p->part_name, "vs_base") == 0)
vs_base_no = part_table_p->part_no;
else if (vs_top_no < 0 &&
strcmp(part_table_p->part_name, "vs_top") == 0)
vs_top_no = part_table_p->part_no;
if (part_table_p->part_global == FALSE) goto NEXT;
ier = fasl_st(part_table_p->part_name, &symval);
#ifdef AOSVS
if (ier == ERSNF) {
FEerror("Internal entry ~S not found.", 1,
make_simple_string(part_table_p->part_name));
} else
if (ier != 0)
sys_emes(ier);
else
part_table_p->part_addr = symval;
#endif
#ifdef DGUX
if (ier != 0) {
FEerror("Internal entry ~S not found.", 1,
make_simple_string(part_table_p->part_name));
} else
part_table_p->part_addr = symval;
#endif
NEXT:
patd_p += 1; /* advance for next */
}
}
rev_pass1()
{
FAS_HDR_P hdr_p;
FAS_REV_P rev_p;
FAS_REVD_P revd_p;
short bnum, rev_count, block_type;
bnum = ((FAS_HDR_P)fas_buffp)->hdr_num;
if (bnum != 2) fasl_invalid();
rev_p = (FAS_REV_P)(fas_buffp + FAS_HEADER_BLEN);
revd_p = (FAS_REVD_P)(rev_p + 1);
rev_count = rev_p->rev_count;
while ( rev_count-- > 0) {
block_type = (revd_p->revd_btyp) & BLOCK_TYPE;
if (block_type != DATA_BLOCK) continue;
datab_rev = (revd_p->revd_brev); /* data block rev */
if (datab_rev > 2) fasl_rev_error();
revd_p += 1; /* advance for next */
}
}
aln_pass1()
{
FAS_HDR_P hdr_p;
FAS_ALN_P aln_p;
short base, power;
aln_p = (FAS_ALN_P)(fas_buffp + FAS_HEADER_BLEN);
base = aln_p->aln_base;
part_table_p = fasl_get_table(base);
part_table_p->part_align = aln_p->aln_power;
}
unexpected()
{
short block_type, block_num;
block_type = (((FAS_HDR_P)fas_buffp)->hdr_typ) & BLOCK_TYPE;
block_num = ((FAS_HDR_P)fas_buffp)->hdr_num;
if (debug) {
printf("unexpected FASL block\n");
printf(" block type : %d\n", block_type);
printf(" block number : %d\n", block_num);
}
fasl_invalid();
}
/* set symbol value in partition table */
/*
fasl_ssym()
{
int symval, i, ier;
char *symp;
for (i = MAX_SYS_PART + 1; i <= max_part_no; i++) {
part_table_p = fasl_get_table(i);
if ((part_table_p->part_symbol == FALSE) &&
(part_table_p->part_global == FALSE)) continue;
symp = part_table_p->part_name;
ier = fasl_st(symp, &symval);
#ifdef AOSVS
if (ier == ERSNF)
if (part_table_p->part_symbol == TRUE)
fasl_undefined(symp);
else
continue;
else
if (ier != 0) sys_emes(ier);
#endif
#ifdef DGUX
if (ier != 0)
if (part_table_p->part_symbol == TRUE) fasl_undefined(symp);
#endif
part_table_p->part_addr = symval;
}
}
*/
fasl_len()
{
int caddr, p_len;
short p_align, i;
caddr = 0;
for (i = 0; i < max_part_no; i++) {
if (i == fas_short_no) continue;
part_table_p = fasl_get_table(i);
if ((part_table_p->part_global == TRUE) &&
(part_table_p->part_addr != 0)) continue;
p_len = part_table_p->part_len;
p_align = part_table_p->part_align;
caddr = fasl_align(caddr, p_align) + p_len;
}
caddr += 2;
/* 1 word for actual length
1 word for alignment gap */
/* warning : for above alignment gap to be proper
all alignment power must be less or equal to 1 */
return(caddr);
}
fasl_align(caddr, power)
int caddr;
short power;
{
int mask;
mask = (1 << power) - 1;
if ((caddr & mask) == 0) return(caddr);
return((caddr | mask) + 1);
}
fasl_saddr()
{
short *caddr;
int i, part_len;
int recno, ind;
short part_align;
caddr = fas_rstart; /* set current to starting addr */
fas_addr_rec_first = fas_temp_last + 1;
fas_addr_rec_curr = 0;
zero(fas_addr_buff, FAS_BUFF_LEN);
for (i = 0; i <= max_part_no; i++) {
part_table_p = fasl_get_table(i);
if ((part_len = part_table_p->part_len) == 0 ||
part_table_p->part_addr != 0) {
recno = i / FAS_ADDRS_IN_REC;
ind = i % FAS_ADDRS_IN_REC;
if (recno > fas_addr_rec_curr) {
fasl_write_addr_rec(fas_addr_rec_curr);
fas_addr_rec_curr++;
zero(fas_addr_buff, FAS_BUFF_LEN);
}
((int *)fas_addr_buff)[ind] = part_table_p->part_addr;
continue;
}
part_align = part_table_p->part_align;
caddr = fasl_align((int)caddr, part_align);
part_table_p->part_addr = caddr;
recno = i / FAS_ADDRS_IN_REC;
ind = i % FAS_ADDRS_IN_REC;
if (recno > fas_addr_rec_curr) {
fasl_write_addr_rec(fas_addr_rec_curr);
fas_addr_rec_curr++;
zero(fas_addr_buff, FAS_BUFF_LEN);
}
((int *)fas_addr_buff)[ind] = caddr;
caddr = caddr + part_len;
}
fasl_write_addr_rec(fas_addr_rec_curr);
}
check_short_area()
{
if (fas_short_no < 0) return;
part_table_p = fasl_get_table(fas_short_no);
if (part_table_p->part_len == 0) return;
if (fas_short_nrel + part_table_p->part_len > fas_short_end)
FEerror("Not enough FASL short nrel area.", 0);
part_table_p->part_addr = fas_short_nrel;
/* for next */
fas_short_nrel += part_table_p->part_len;
}